/**
 * 
 */
package cl.hhha.web.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

import cl.hhha.web.dao.GenericDao;
import cl.hhha.web.model.EstadoFormulario;
import cl.hhha.web.model.Formulario;
import cl.hhha.web.model.Solicitante;
import cl.hhha.web.service.FormularioOirsManager;

/**
 * @author Óscar Álvarez V
 * @email oialvarez@gmail.com
 * @Version 1.0
 * @date 25-06-2009 19:31:32
 */
public class FormularioOirsManagerImpl extends GenericManagerImpl<Formulario, Long>
implements FormularioOirsManager {

	GenericDao<Solicitante, Long> solicitanteDao;

	public void setSolicitanteDao(GenericDao<Solicitante, Long> solicitanteDao) {
		this.solicitanteDao = solicitanteDao;
	}

	/**
	 * 
	 * @param genericDao
	 */
	public FormularioOirsManagerImpl(GenericDao<Formulario, Long> genericDao) {
		super(genericDao);
	}

	/**
	 * 1.- Permite guardar o modificar un formulario oirs,
	 * 2.- envia un correo al solicitante en caso que el correo sea especificado
	 * 3.- Genera un ticket para que el solicitante revise sus formularios externamente.
	 * 4.- En caso de ser nuevo el formulario, se le asignará el estado ingresado.
	 * 
	 * @return El objeto sincronizado con el origen de datos.
	 * @throws IllegalArgumentException en caso que el formulario o solicitante sean nulos.
	 * @see cl.hhha.web.service.impl.GenericManagerImpl#save(java.lang.Object)
	 */
	@Override
	public Formulario save(Formulario f) {
		if(f==null){
			throw new IllegalArgumentException("El formulario no puede ser nulo");
		}

		if(f.getSolicitante()==null){
			throw new IllegalArgumentException("El solicitante no puede ser nulo");
		}

		// si el formulario es nuevo
		if(f.getId() == null){

			EstadoFormulario efo = new EstadoFormulario();
			efo.setId(1L);//TODO extraer el estado ingresado desde el exterior.
			f.setEstado(efo);

			//se asigna la fecha de ingreso
			f.setFechaIngreso(new Date(System.currentTimeMillis()));

		}

		//Se obtiene una referencia al solicitante del formulario
		Solicitante sol = f.getSolicitante();

//		// si el solicitante es nuevo.
		if(sol.getId() == null) {

			HashMap<String, Object> parametros = new HashMap<String, Object>();
			parametros.put("rut", sol.getRut());
			List<Solicitante> solicitantes = solicitanteDao.findByNamedQuery("buscarSolicitantePorRut", parametros);

			//Si el solicitante ya está ingresado
			if(!solicitantes.isEmpty()) { 

				Solicitante solicitanteIngresado = solicitantes.iterator().next();
				//se sincroniza para la modificación.
				sol.setId(solicitanteIngresado.getId());
				sol.setTicket(solicitanteIngresado.getTicket());

				if(log.isDebugEnabled()){
					log.debug("Se encontró el solicitante " + solicitanteIngresado);
				}
				
			}

		} else {
			Solicitante solicitanteIngresado = solicitanteDao.get(sol.getId());
			sol.setTicket(solicitanteIngresado.getTicket());
			
			if(log.isDebugEnabled()){
				log.debug("Se encontró el solicitante " + solicitanteIngresado);
			}
			
		}
		
		

		if(log.isDebugEnabled()){
			log.debug("Ticket -> " + sol.getTicket());
		}

		// si el solicitante no tiene ticket asignado
		if( !sol.tieneTicket()) {

			//El ticket será un numero entre 1 y 999 inclusive
			Long ticket = (System.currentTimeMillis() & 998l) + 1;
			sol.setTicket(ticket.intValue());	
			
			if(log.isDebugEnabled()){
				log.debug("Se ha generado un ticket -> " + sol.getTicket());
			}

		} 

		if(sol.tieneCorreoElectronico() ){
			//enviar correo electronico.
		}


//		sol = solicitanteDao.save(sol);
//		f.setSolicitante(sol);

		return super.save(f);
	}

	/**
	 * {@inheritDoc}
	 */
	public List<Formulario> getSolicitudesIngresadas() {
		HashMap<String, Object> params = new HashMap<String, Object>();
		EstadoFormulario efo = new EstadoFormulario();
		efo.setId(1L);//TODO extraer el estado ingresado desde el exterior.
		params.put("estado", efo);
		return super.genericDao.findByNamedQuery("buscarFormularioPorEstado", params);
	}

	/**
	 * {@inheritDoc}
	 */
	public Formulario tomarConocimiento(Formulario formularioOirs) {
		formularioOirs = super.get(formularioOirs.getId());
		EstadoFormulario efo = new EstadoFormulario();
		efo.setId(2L);//TODO extraer el estado toma conocimiento desde el exterior
		formularioOirs.setEstado(efo);
		return super.save(formularioOirs);
	}


	public List<Formulario> getSolicitudesPorTicket(Formulario f) {
		if(f==null){
			throw new IllegalArgumentException("El formulario no puede ser nulo");
		}

		if(f.getSolicitante()==null){
			throw new IllegalArgumentException("El solicitante no puede ser nulo");
		}
		
		Solicitante s = f.getSolicitante();
		
		HashMap<String , Object> parametros = new HashMap<String, Object>();
		parametros.put("rut", s.getRut());
		parametros.put("ticket", s.getTicket());
		
		return super.genericDao.findByNamedQuery("buscarFormularioPorRutTicket", parametros);
	}
	
	public static void main(String [] args){
		for(Integer index = 0; index < 1001; index ++){
			System.out.println(index + " & 1000l => " + (index & 511l));
		}
	}
}
